﻿using System.Collections.Concurrent;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using net.xBei.Helper;
using net.xBei.Models;
using net.xBei.WebApi.FrameworkExtensions;
using net.xBei.WebApi.Helper;

namespace net.xBei.WebApi.Repository {
    /// <summary>
    /// 用户权限认证服务
    /// </summary>
    public class AuthorizationRepository : IAuthorizationRepository, IAutoRegisterRepository {
        private readonly ApiCallerFactory apiCallerFactory;
        private readonly HttpContext? httpContext;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="accessor"></param>
        /// <param name="apiCallerFactory"></param>
        public AuthorizationRepository(IHttpContextAccessor accessor,
                                      ApiCallerFactory apiCallerFactory) {
            this.apiCallerFactory = apiCallerFactory;
            httpContext = accessor.HttpContext;
        }

        /// <summary>
        /// 当前用户ID，未登录返回-1
        /// </summary>
        public int UserId {
            get {
#if DEBUG
                var id = HttpContext?.GetCurrentUserId() ?? -1;
                return id > 0 ? id : 1;
#else
                return HttpContext?.GetCurrentUserId() ?? -1;
#endif
            }
        }
        /// <inheritdoc/>
        public bool IsSystemUser =>
                    HttpContext != null && HttpContext.User != null && HttpContext.User.Identity != null
                    && HttpContext.User.Identity.Name == CommonConsts.SystemUserId;
        /// <inheritdoc/>
        public HttpContext? HttpContext => httpContext;

        /// <inheritdoc/>
        public Task<bool> IsAdminAsync() => IsAdminAsync(UserId);
        /// <inheritdoc/>
        public async Task<bool> IsAdminAsync(int userId) {
            if (userId < 1) return false;
            if (AdminList.ContainsKey(userId)) return AdminList[userId];
            var isAdmin = HttpContext?.User.IsInRole("Admin") == true;
            //if (!isAdmin) {
            //    isAdmin = await apiCallerFactory.GetTokenService()
            //                                    .IsAdminAsync(userId);
            //}
            AdminList.TryAdd(userId, isAdmin);
            return await Task.FromResult(isAdmin);
        }

        private static readonly ConcurrentDictionary<int, bool> AdminList = new();
        /// <inheritdoc/>
        public Task<bool> IsBackUserAsync() => IsBackUserAsync(UserId);

        /// <inheritdoc/>
        public Task<bool> IsBackUserAsync(int userId)
            => Task.FromResult(userId >= 1
                && HttpContext?.User.GetIntValue(AuthorizationHandler.ClaimUserType, 0)
                               .GetEnum(CommonConsts.UserType.GUEST)
                               .HasFlag(CommonConsts.UserType.BACKEND) == true);
        //return await apiCallerFactory.GetService("User").IsBackUserAsync(userId);

        /// <inheritdoc/>
        public async Task<bool> CheckUserPermissionAsync(int userId, string controller, string action, string permissionKey = "A")
            => await apiCallerFactory.GetTokenService()
                                     .CheckUserPermissionAsync(userId, controller, action, permissionKey);
        //=> await Task.FromResult(true);
    }
}
